package se.webbzon.oschi01.worldcamera;

import se.webbzon.oschi01.utilities.NotImplementedException;

public class Polygon implements Area {
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 6006790660930940382L;

	// The boundary of this polygon
	protected final Rectangle boundary;
	
	// The number of vertices in this polygon
	protected int vertices;
	
	// The vertices of this polygon
	protected double[] x, y;
	
	/*============================================================
	Constructors
	============================================================*/
	
	public Polygon() {
		x = new double[] {0,1,0};
		y = new double[] {0,0,1};
		boundary = new Rectangle();
		vertices = 3;
	}
	
	public Polygon(double[] x, double[] y) {
		if (x.length != y.length)
			throw new IllegalArgumentException("x and y must have the same size.");
		this.x = x;
		this.y = y;
		vertices = x.length;
		double xMin = x[0];
		double yMin = x[0];
		double xMax = x[0];
		double yMax = x[0];
		for (int n = 1; n < x.length; n++) {
			xMin = Math.min(xMin, x[n]);
			yMin = Math.min(yMin, y[n]);
			xMax = Math.max(xMax, x[n]);
			yMax = Math.max(yMax, y[n]);
		}
		boundary = new Rectangle(xMin,yMin,xMax - xMin,yMax - yMin);
	}
	
	/*============================================================
	Public Methods
	============================================================*/
	
	/** Adds a new vertex to this polygon. **/
	public void addVertex(double x, double y) {
		if (this.x.length == vertices) {
			double[] newX = new double[2*this.x.length];
			double[] newY = new double[2*this.y.length];
			System.arraycopy(this.x, 0, newX, 0, 2*vertices);
			System.arraycopy(this.y, 0, newY, 0, 2*vertices);
			this.x = newX;
			this.y = newY;
		}
		this.x[vertices] = x;
		this.y[vertices] = y;
		vertices++;
		
		if (!boundary.contains(x, y)) {
			double bx = boundary.getX();
			double by = boundary.getY();
			double nx = Math.min(x, bx);
			double ny = Math.min(y, by);
			double nw = Math.max(x - nx, boundary.getWidth());
			double nh = Math.max(y - ny, boundary.getHeight());
			boundary.set(nx, ny, nw, nh);
		}
	}
	
	/** Resets this polygon. **/
	public void reset() {
		x = new double[] {0,1,0};
		y = new double[] {0,0,1};
		boundary.set(0, 0, 1, 1);
		vertices = 3;
	}
	
	/** Returns the (n+1):th x-coordinate of this polygon. **/
	public double getX(int n) {
		return x[n];
	}
	
	/** Returns the (n+1):th y-coordinate of this polygon. **/
	public double getY(int n) {
		return y[n];
	}
	
	/** Returns the number of vertices of this polygon. **/
	public int getVertices() {
		if (x == null)
			return 0;
		else
			return x.length;
	}
	
	@Override public boolean contains(double x, double y) {
		if (this.x == null)
			return false;
		else
			throw new NotImplementedException();
	}

	@Override public void getBoundary(Rectangle boundary) {
		boundary.set(this.boundary);
	}
	
	@Override public Polygon clone() {
		return new Polygon(x,y);
	}

}
